package org.rujue.common.utils;

import java.math.BigDecimal;

public class BigDecimal2Chinese {

    // 定义现金单位字符串数组，用于大写金额转换
    static String cashUnitLeft[] = { "元", "拾", "佰", "仟", "万", "拾", "佰", "仟","亿", "拾", "佰", "仟", "万" };
    static String cashUnitRight[] = { "角", "分", "厘" };
    // 定义数字到大写转换的字符串数组
    static String upperNumber[] = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒","捌", "玖" };

    /**
     * 公共方法，用于将BigDecimal类型的金额转换为大写字符串
     * @param money BigDecimal类型的金额
     * @return 转换后的大写字符串
     */
    public static String convert(BigDecimal money) {
        String smoney = money.toString();
        try{
            // 把数值分为整数型和带小数的数值分开处理
            if (smoney.indexOf(".") != -1) {
                // 处理整数部分
                String left = smoney.substring(0, smoney.indexOf("."));
                // 处理小数部分
                String right = smoney.substring(smoney.indexOf(".") + 1);
                String result = convertLeft(left) + convertRight(right);
                return result;
            } else {
                return convertLeft(smoney);
            }
        } catch(IllegalArgumentException e){
            System.out.println(e.getMessage());
            System.out.println("请输入转换范围内现金");
            return null;
        }
    }

    /**
     * 处理金额的整数部分转换为大写
     * @param left 金额的整数部分字符串
     * @return 转换后的大写字符串
     */
    private static String convertLeft(String left) {
        int length = left.length();
        // 根据单位'亿','万','元'，把整数部分分为3种情况处理
        if (length <= 4) { // 金额在千元以内
            // 金额为'0'元时的特殊情况
            if(length == 1 && Integer.valueOf(left) == 0)
                return "零元";
            return convertPart(left, length);
        } else if (length <= 8) { // 金额在千万元以内
            // 从左侧字符串中提取除最后四个字符之外的部分
            String part1 = left.substring(0, length - 4);
            // 从左侧字符串中提取最后四个字符
            String part2 = left.substring(length - 4, length);
            // 对提取出的除最后四个字符之外的部分进行转换
            String result1 = convertPart(part1, length);
            // 对提取出的最后四个字符进行转换
            String result2 = convertPart(part2, 4);
            // part1是以0结尾，则result1追加“零”
            if(part1.endsWith("0") && !part2.startsWith("0")){
                result1 = result1.concat("零");
            }
            return result1 + result2;
        } else if (length <= 12) { // 金额在千亿元以内
            String part1 = left.substring(0, length - 8);
            String part2 = left.substring(length - 8, length - 4);
            String part3 = left.substring(length - 4, length);
            String result1 = convertPart(part1, length);
            String result2 = convertPart(part2, 8);
            String result3 = convertPart(part3, 4);
            String result = result1 + result2 + result3;
            return result;
        } else {
            throw new IllegalArgumentException("超出转换数值范围！");
        }
    }

    /**
     * 处理金额的小数部分转换为大写
     * @param right 金额的小数部分字符串
     * @return 转换后的大写字符串
     */
    private static String convertRight(String right) {
        String result = "";
        String number = "";
        String unit = "";
        int length = right.length();
        // 遍历小数部分的每一位，进行转换
        for (int i = 0; i < length; i++) {
            String detail = right.substring(i, i + 1);
            int value = Integer.valueOf(detail);
            number = upperNumber[value];
            unit = cashUnitRight[i];
            result = result.concat(number).concat(unit);
        }
        // 如果为“零角零分”，则返回“整”
        if (result.equals("零角零分")) {
            return "整";
        }
        if (result.endsWith("零分")) {
            return result.replaceAll("零分", "整");
        }
        // 如果包含“零角”并以“分”结尾，则把零移到角位
        if (result.contains("零角") && result.endsWith("分")) {
            result = result.replaceAll("零角", "零");
        }
        return result;
    }

    /**
     * 转换金额的指定部分为大写
     * @param part 待转换的金额部分字符串
     * @param position 金额部分的位置，用于确定单位
     * @return 转换后的大写字符串
     */
    private static String convertPart(String part, int position) {
        String result = "";
        String number = "";
        String unit = "";
        // 排除单位为'万'时，四位数值均为'0'的情况
        if(part.equals("0000") && position == 8)
            return "";
        // 遍历金额部分的每一位，进行转换
        for (int i = 0; i < part.length(); i++) {
            int value = Integer.valueOf(String.valueOf(part.charAt(i)));
            number = upperNumber[value];
            unit = cashUnitLeft[position - 1 - i];
            result = result.concat(number).concat(unit);
        }
        // 进行多余的零的优化处理
        result = result.replaceAll("零仟", "零").replaceAll("零佰", "零")
                .replaceAll("零拾", "零").replaceAll("零零", "零")
                .replaceAll("零零", "零").replaceAll("零亿", "亿")
                .replaceAll("零万", "万").replaceAll("零元", "元");
        return result;
    }

    public static void main(String[] args) {
//        System.out.println(convert(new BigDecimal("0.00")));
//        System.out.println(convert(new BigDecimal("1.00")));
//        System.out.println(convert(new BigDecimal("1.45")));
//        System.out.println(convert(new BigDecimal("10.00")));
//        System.out.println(convert(new BigDecimal("10.05")));
//        System.out.println(convert(new BigDecimal("10.40")));
//        System.out.println(convert(new BigDecimal("10.45")));
//        System.out.println(convert(new BigDecimal("12.45")));
//        System.out.println(convert(new BigDecimal("12.00")));
//        System.out.println("=============三位数============");
//        System.out.println(convert(new BigDecimal("123.45")));
//        System.out.println(convert(new BigDecimal("102.00")));
//        System.out.println(convert(new BigDecimal("120.00")));
//        System.out.println("==============四位数===========");
//        System.out.println(convert(new BigDecimal("1000.00")));
//        System.out.println(convert(new BigDecimal("1020.00")));
//        System.out.println(convert(new BigDecimal("1002.00")));
//        System.out.println(convert(new BigDecimal("1022.00")));
//        System.out.println(convert(new BigDecimal("1200.00")));
//        System.out.println(convert(new BigDecimal("1202.00")));
//        System.out.println(convert(new BigDecimal("1220.00")));
//        System.out.println("==============五位数===========");
//        System.out.println(convert(new BigDecimal("10000.00")));
//        System.out.println(convert(new BigDecimal("12000.00")));
//        System.out.println(convert(new BigDecimal("10200.00")));
//        System.out.println(convert(new BigDecimal("10020.00")));
//        System.out.println(convert(new BigDecimal("10002.00")));
//
//        System.out.println(convert(new BigDecimal("10022.00")));
//        System.out.println(convert(new BigDecimal("12200.00")));
//        System.out.println(convert(new BigDecimal("10202.00")));
//        System.out.println(convert(new BigDecimal("12020.00")));
//        System.out.println(convert(new BigDecimal("10220.00")));
//        System.out.println(convert(new BigDecimal("12002.00")));
//
//        System.out.println(convert(new BigDecimal("10222.00")));
//        System.out.println(convert(new BigDecimal("12022.00")));
//        System.out.println(convert(new BigDecimal("12202.00")));
//        System.out.println(convert(new BigDecimal("12220.00")));
//        System.out.println("============六位数=============");
//        System.out.println(convert(new BigDecimal("100000.00"))); // 壹拾万元整
//        System.out.println(convert(new BigDecimal("100002.00")));
//        System.out.println(convert(new BigDecimal("100020.00")));
//        System.out.println(convert(new BigDecimal("100200.00")));
//        System.out.println(convert(new BigDecimal("102000.00")));
//        System.out.println(convert(new BigDecimal("120000.00")));
//
//        System.out.println(convert(new BigDecimal("100022.00")));
//        System.out.println(convert(new BigDecimal("100220.00")));
//        System.out.println(convert(new BigDecimal("100202.00")));
//        System.out.println(convert(new BigDecimal("102200.00")));
//        System.out.println(convert(new BigDecimal("102020.00")));
//        System.out.println(convert(new BigDecimal("102200.00")));
//        System.out.println(convert(new BigDecimal("120002.00")));
//        System.out.println(convert(new BigDecimal("120020.00")));
//        System.out.println(convert(new BigDecimal("120200.00")));
//        System.out.println(convert(new BigDecimal("122000.00")));
//        System.out.println("=============七位数============");
//        System.out.println(convert(new BigDecimal("1000000.00")));
//        System.out.println(convert(new BigDecimal("1000002.00")));
//        System.out.println(convert(new BigDecimal("1000020.00")));
//        System.out.println(convert(new BigDecimal("1000200.00")));
//        System.out.println(convert(new BigDecimal("1002000.00")));
//        System.out.println(convert(new BigDecimal("1020000.00")));
//        System.out.println(convert(new BigDecimal("1200000.00")));
//        System.out.println("=========================");
//        System.out.println(convert(new BigDecimal("1220000.00")));
//        System.out.println(convert(new BigDecimal("1202000.00")));
//        System.out.println(convert(new BigDecimal("1200200.00")));
//        System.out.println(convert(new BigDecimal("1200020.00")));
//        System.out.println(convert(new BigDecimal("1200002.00")));
//        System.out.println(convert(new BigDecimal("1220000.00")));
//        System.out.println("=========================");
        System.out.println(convert(new BigDecimal("1222000.00")));
        System.out.println(convert(new BigDecimal("1220200.00")));
        System.out.println(convert(new BigDecimal("1220020.00")));
        System.out.println(convert(new BigDecimal("1220002.00")));
        System.out.println(convert(new BigDecimal("1002220.00")));
        System.out.println(convert(new BigDecimal("1002202.00")));
        System.out.println(convert(new BigDecimal("1002022.00")));
        System.out.println(convert(new BigDecimal("1000222.00")));

        System.out.println(convert(new BigDecimal("1022200.00")));
        System.out.println(convert(new BigDecimal("1022002.00")));
        System.out.println(convert(new BigDecimal("1020220.00")));
        System.out.println(convert(new BigDecimal("1020022.00")));
        System.out.println(convert(new BigDecimal("1020202.00")));
        System.out.println(convert(new BigDecimal("1022020.00")));
    }
}
